home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 40
/
Amiga Format CD40 (1999-05-11)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-06].iso
/
-in_the_mag-
/
recent_reviews
/
drivelight
/
requeststring.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-31
|
10KB
|
355 lines
/*
* RequestString
*
* A program which requests a string from the user and prints it on
* the standard output.
*
* Written by Peter Bengtsson who does not agree to be held responsible
* for any damage or loss resulting from the use of this program.
*
* Use it as you wish for any and all nice things you can think of.
*/
#include <proto/exec.h>
#include <exec/memory.h>
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#include <clib/intuition_protos.h>
#include <pragmas/intuition_pragmas.h>
#include <clib/graphics_protos.h>
#include <pragmas/graphics_pragmas.h>
#include <clib/gadtools_protos.h>
#include <pragmas/gadtools_pragmas.h>
#include <graphics/gfxbase.h>
#include <utility/tagitem.h>
#include <utility/hooks.h>
#include <intuition/sghooks.h>
#include <intuition/intuition.h>
#include <clib/alib_protos.h>
#include <string.h>
LONG __saveds RequestString(void);
ULONG __saveds __asm HookFunc(register __a0 struct Hook *TheHook,
register __a2 struct SGWork *Obj,
register __a1 APTR Mess);
#define TEMPLATE "STRING,TEXT/K,TITLE/K,NOGADS/S,WIDTH/N,SAFE/S,PERSIST/S,ENCRYPT/S,COMPARE/K,PUBSCREEN/K"
#define NArgs 10 /* Number of arguments */
#define STRING 0
#define TEXT 1
#define TITLE 2
#define NOGADS 3
#define WIDTH 4
#define SAFE 5
#define PERSIST 6
#define ENCRYPT 7
#define COMPARE 8
#define PUBSCREEN 9
#define MINWIDTH 8 /* Minimum width of gadget in characters */
LONG __saveds RequestString(void)
{
struct DosLibrary *DOSBase=NULL;
struct Library *GadToolsBase=NULL;
struct IntuitionBase *IntuitionBase=NULL;
struct GfxBase *GfxBase=NULL;
LONG ArgList[NArgs];
ULONG MsgClass=0;
APTR VisInfo=NULL;
char CBuffer[12],UName[48];
struct TextExtent TExtent;
struct Hook SGHook={0,0,0};
struct RDArgs *Args=NULL;
struct ExtIntuiMessage *EIMess=NULL;
struct Gadget *Gad=NULL,*GList=NULL;
struct Window *Win=NULL;
struct Screen *Scr=NULL;
char *ReturnText=NULL;
int WWidth=0,WHeight=0;
int GWidth=32,GHeight=1;
long TXPos=0,TYPos=0;
LONG Ret=20;
const char *v="$VER: RequestString 39.4 (18.05.97)"; /* Bump this to 4X.1? */
struct TagItem WindowTags[]={
{WA_PubScreen,0},
{WA_Gadgets,0},
{WA_Left,0},
{WA_Top,0},
{WA_Width,0},
{WA_Height,0},
{WA_DragBar,FALSE},
{WA_DepthGadget,FALSE},
{WA_CloseGadget,FALSE},
{WA_Title,NULL},
{WA_IDCMP,IDCMP_GADGETUP|IDCMP_INACTIVEWINDOW|IDCMP_ACTIVEWINDOW|IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW},
{WA_SizeGadget,FALSE},
{WA_Activate,TRUE}
};
struct NewGadget StringGad={10,5,80,15,NULL,NULL,0,0L,NULL,NULL};
if((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",39L))!=NULL){
if((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39L))!=NULL){
if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39L))!=NULL){
if((GadToolsBase=OpenLibrary("gadtools.library",39L))!=NULL){
memset(ArgList,0,NArgs*sizeof(LONG)); /* Clear the ArgList array */
Args=ReadArgs(TEMPLATE,ArgList,NULL); /* How do we check for failure? */
if((Scr=LockPubScreen((UBYTE *)ArgList[PUBSCREEN]))!=NULL){
if((VisInfo=GetVisualInfo(Scr,NULL))!=NULL){
if((Gad=CreateContext(&GList))!=NULL){
if(ArgList[WIDTH]!=0)GWidth = *((LONG *)ArgList[WIDTH]);
if(GWidth<8)GWidth=8;
GHeight=GHeight*Scr->RastPort.TxHeight+6;
WHeight=GHeight+8;
do{
GWidth=GWidth*Scr->RastPort.TxWidth+4;
WWidth=GWidth+20;
if(WWidth>Scr->Width)
GWidth=(Scr->Width-20)/(Scr->RastPort.TxWidth)-1;
}while(WWidth>Scr->Width);
/* Forbid()/Permit() around this following poking in GfxBase? */
FontExtent(GfxBase->DefaultFont,&TExtent);
if(ArgList[TEXT]!=0){
WHeight+=(TExtent.te_Height);
if((TExtent.te_Width*strlen((char *)ArgList[TEXT])+20)>WWidth)
WWidth=(TExtent.te_Width*strlen((char *)ArgList[TEXT])+20);
}
/* If the window has a title, it will also have a dragbar, closegadget
* and a depthgadget.
*/
if(ArgList[TITLE]!=0){
WindowTags[6].ti_Data=TRUE;
if(ArgList[NOGADS]==0){
WindowTags[7].ti_Data=TRUE;
WindowTags[8].ti_Data=TRUE;
}
WindowTags[9].ti_Data=(ULONG)ArgList[TITLE];
WHeight+=Scr->RastPort.TxHeight; /* Should be Win->BorderTop, see also note below. */
}
StringGad.ng_VisualInfo=VisInfo;
StringGad.ng_Width=GWidth;
StringGad.ng_Height=GHeight;
StringGad.ng_TopEdge=WHeight-(GHeight+4); /* The '4' should be replaces by Win->BorderTop but how? The window is not yet opened. */
StringGad.ng_LeftEdge=(WWidth-GWidth)>>1;
/* Initialize the Hook if we are using a safe stringgadget.
* SGHook.d_Data points to storage space for the string which
* will be returned. Memory sould be cleared.
*/
if(ArgList[SAFE]!=0){
SGHook.h_Entry=(unsigned long (*)())HookFunc;
/* SGHook.h_SubEntry=NULL; */
SGHook.h_Data=AllocVec(98,MEMF_ANY|MEMF_CLEAR); /* Should be made dynamic if possible */
if(ArgList[STRING]!=0){
int i = -1;
strcpy((char *)SGHook.h_Data,(char *)ArgList[STRING]);
while(((char *)ArgList[STRING])[++i]!=0)((char *)ArgList[STRING])[i]='*';
}
}
/* Here goes nothing... */
if((Gad=CreateGadget(STRING_KIND,Gad,&StringGad,GTST_EditHook,(ArgList[SAFE]==0)?NULL:&SGHook,GTST_String,ArgList[STRING],TAG_END))!=NULL){
/* Screen Gadget */
WindowTags[0].ti_Data=(ULONG)Scr;
WindowTags[1].ti_Data=(ULONG)GList;
/* Width & Height */
WindowTags[4].ti_Data=(ULONG)WWidth;
WindowTags[5].ti_Data=(ULONG)WHeight;
/* X & Y Pos */
WindowTags[2].ti_Data=(ULONG)(Scr->Width-WWidth)>>1;
WindowTags[3].ti_Data=(ULONG)(Scr->Height-WHeight)>>1;
if((Win=OpenWindowTagList(NULL,WindowTags))!=NULL){
/* Is there some (un)informative text in the window? */
if(ArgList[TEXT]!=0){
SetAPen(Win->RPort,1); /* Colour should rather be selected with thougt to the background of the window, fix this. */
TXPos=(WWidth-TextLength(Win->RPort,(char *)ArgList[TEXT],(unsigned long)strlen((char *)ArgList[TEXT])))>>1;
TYPos=GfxBase->DefaultFont->tf_Baseline+Win->BorderTop+1;
Move(Win->RPort,TXPos,TYPos);
Text(Win->RPort,(char *)ArgList[TEXT],(unsigned long)strlen((char *)ArgList[TEXT]));
}
do{
WaitPort(Win->UserPort);
EIMess=(struct ExtIntuiMessage *)GT_GetIMsg(Win->UserPort);
MsgClass=EIMess->eim_IntuiMessage.Class;
GT_ReplyIMsg((struct IntuiMessage *)EIMess);
switch(MsgClass) {
case IDCMP_ACTIVEWINDOW :
ActivateGadget(Gad,Win,NULL);
break;
case IDCMP_INACTIVEWINDOW :
if(ArgList[PERSIST]){
ScreenToFront(Win->WScreen);
WindowToFront(Win);
ActivateWindow(Win);
}
break;
case IDCMP_REFRESHWINDOW :
GT_BeginRefresh(Win);
if(ArgList[TEXT]!=0){
Move(Win->RPort,TXPos,TYPos);
Text(Win->RPort,(char *)ArgList[TEXT],(unsigned long)strlen((char *)ArgList[TEXT]));
}
GT_EndRefresh(Win,TRUE);
break;
}
}while((MsgClass!=IDCMP_GADGETUP) && (MsgClass!=IDCMP_CLOSEWINDOW));
GT_GetGadgetAttrs(Gad,Win,NULL,GTST_String,&ReturnText,TAG_END);
if(ArgList[SAFE]!=0)ReturnText=(char *)SGHook.h_Data;
/* Try to find out who the user is if we are to encrypt the output. */
/* I really don't know how to acquire the username, but this might */
/* be a good guess of how to do it. */
if(ArgList[ENCRYPT]!=0){
if(GetVar("USER",UName,47,0L)==-1)
if(GetVar("USERNAME",UName,47,0L)==-1)
if(GetVar("LOGIN",UName,47,0L)==-1)
UName[0]=0;
ACrypt(CBuffer,ReturnText,UName);
ReturnText=CBuffer;
}
Printf("\"%s\"\n",ReturnText);
/* Here follows the COMPARE parameter. If the input string is not equal
* to the argument of COMPARE we return WARN.
*/
if(ArgList[COMPARE]!=0)
Ret=(strcmp(ReturnText,(char *)ArgList[COMPARE]))?RETURN_WARN:0;
else
Ret=0;
}}}} /* if:s */
/* LockPubScreen failure only warrants a 10 if user defined a screen */
} else if(ArgList[PUBSCREEN]!=0)Ret=10;
/* Clean up. */
if(SGHook.h_Data!=NULL)FreeVec(SGHook.h_Data);
if(Args)FreeArgs(Args);
if(Win)CloseWindow(Win);
if(GList)FreeGadgets(GList);
if(VisInfo)FreeVisualInfo(VisInfo);
if(Scr)UnlockPubScreen(NULL,Scr);
CloseLibrary(GadToolsBase);
}
CloseLibrary((struct Library *)IntuitionBase);
}
CloseLibrary((struct Library *)GfxBase);
}
CloseLibrary((struct Library *)DOSBase);
}
return(Ret);
}
/* EditHook function for safe stringgadgets */
ULONG __saveds __asm HookFunc(register __a0 struct Hook *TheHook,
register __a2 struct SGWork *Obj,
register __a1 ULONG *Mess)
{
int i0,i1;
char * const Tmp=(char *)(TheHook->h_Data);
if(Mess[0]==SGH_KEY)
{
Obj->Actions|=SGA_USE;
switch(Obj->EditOp)
{
case EO_DELBACKWARD :
i0=Obj->StringInfo->BufferPos;
i1=(Obj->StringInfo->NumChars)-(Obj->NumChars);
strcpy(&Tmp[i0-i1],&Tmp[i0]);
break;
case EO_DELFORWARD :
i0=Obj->StringInfo->BufferPos;
i1=(Obj->StringInfo->NumChars)-(Obj->NumChars);
strcpy(&Tmp[i0],&Tmp[i0+i1]);
break;
case EO_ENTER :
/* Exit handling. */
break;
case EO_RESET :
Tmp[0]=0;
break;
case EO_INSERTCHAR :
if(strlen(Tmp)>96)Obj->Actions&=~SGA_USE;
i0=Obj->StringInfo->BufferPos;
Obj->WorkBuffer[i0]='*';
i1=strlen(Tmp)+1;
while(i1--!=i0)Tmp[i1+1]=Tmp[i1];
Tmp[i0]=Obj->Code;
break;
case EO_CLEAR :
Tmp[0]=0;
break;
case EO_BIGCHANGE : /* Not Allowed */
case EO_UNDO :
case EO_SPECIAL :
Obj->Actions&=~SGA_USE;
break;
}
return(~0);
} else {
Obj->Actions&=~SGA_USE;
return(0);
}
}